const app = getApp();
// var wxCharts = require('../../utils/wxcharts.js');
var lineChart = null;

function inArray(arr, key, val) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i;
    }
  }
  return -1;
}

//字符串转buffer 十六进制
function stringToHexBuffer(data) {
  var typedArray = new Uint8Array(data.match(/[\da-f]{2}/gi).map(function (h) {
    return parseInt(h, 16)
  }))

  return typedArray.buffer
}

// 字符串转byte
function stringToBytes(str) {
  var array = new Uint8Array(str.length);
  for (var i = 0, l = str.length; i < l; i++) {
    array[i] = str.charCodeAt(i);
  }
  console.log(array);
  return array.buffer;
}  

// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  var hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('');
}

Page({
  data: {
    devices: [],
    connected: false,
    chs: [],
    datas: [],// 一个图表能容纳的数据数组
    secondDatas: [],// 刷新一次图表所能容纳数据的数组
    allDatas: [],// 发送后台数据容纳的数组
    // 三个轴的数据数组，如果是空数组，图表控件是不能绘制完成的，所以这里起始值不能给空数组
    xData: [0],
    yData: [0],
    zData: [0]
  },

/////////////////////////  图表相关 /////////////////////////////

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.createBLEConnection();
   
    var that = this;

    // 注：画布的高度在app.wxss中设置 这里设置画布的宽为屏幕的宽
    var windowWidth = 320;
    try {
      var res = wx.getSystemInfoSync();
      windowWidth = res.windowWidth;
    } catch (e) {
      console.error('getSystemInfoSync failed!');
    }

    var simulationData = this.createSimulationData();
    lineChart = new wxCharts({
      canvasId: 'lineCanvas',
      type: 'line',                          // 图表类型
      categories: simulationData.categories, // x轴坐标点
      // background: '#f5f5f5',
      series: [{
        name: 'X轴加速度',
        data: that.data.xData,
        format: function (val, name) {
          return val.toFixed(2);
        }
      }, {
        name: 'Y轴加速度',
        data: that.data.yData,
        format: function (val, name) {
          return val.toFixed(2);
        }
      }, {
          name: 'Z轴加速度',
          data: that.data.zData,
          format: function (val, name) {
            return val.toFixed(2);
          }
      }],
      xAxis: {
        disableGrid: true
      },
      yAxis: {
        title: '',
        format: function (val) {
          return val.toFixed(0);
        },
        min: -30,   // 固定最小值
        max: 30     // 固定最大值
      },
      width: windowWidth,               // 图表宽度
      height: 400,                      // 图表高度 注：需要和app.wxss中canvas设置保持一致
      dataLabel: false,                 // 是否显示每个点的数据
      dataPointShape: false,            // 每个点是否画点出来
      animation: false,                 // 是否需要动画展示 数据加载
      subtitle: '空间加速度X、Y、Z',      // 图表标题
      extra: {
        lineStyle: 'curve'
      }
    });
  },

  // 创建图表数据 x轴的坐标
  createSimulationData: function () {
    var categories = [];
    var data = [];
    for (var i = 0; i < 100; i++) {
      categories.push(i);
    }
    return {
      categories: categories
    }
  },

  // 刷新图表数据
  updateData: function () {
    var that = this;
    var simulationData = this.createSimulationData();
    var series = [{
      name: 'X轴加速度',
      data: that.data.xData,
      format: function (val, name) {
        return val.toFixed(2);
      }
    }, {
      name: 'Y轴加速度',
      data: that.data.yData,
      format: function (val, name) {
        return val.toFixed(2);
      }
    }, {
      name: 'Z轴加速度',
      data: that.data.zData,
      format: function (val, name) {
        return val.toFixed(2);
      }
    }];
    lineChart.updateData({
      categories: simulationData.categories,
      series: series
    });
  },
  
  /////////////////////////  蓝牙相关 /////////////////////////////

  /**
   * 打开蓝牙适配器
   */
  openBluetoothAdapter() {
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('openBluetoothAdapter success', res)
        this.startBluetoothDevicesDiscovery()
      },
      fail: (res) => {
        if (res.errCode === 10001) {
          wx.onBluetoothAdapterStateChange(function (res) {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              this.startBluetoothDevicesDiscovery()
            }
          })
        }else{
          console.log('onBluetoothAdapterStateChange fail', res)
        }
      }
    })
  },
  /**
   * 获取蓝牙适配器状态
   */
  getBluetoothAdapterState() {
    wx.getBluetoothAdapterState({
      success: (res) => {
        console.log('getBluetoothAdapterState', res)
        if (res.discovering) {
          this.onBluetoothDeviceFound()
        } else if (res.available) {
          this.startBluetoothDevicesDiscovery()
        }
      },
      fail(res){
        console.log('getBluetoothAdapterState fail', res)
      }
    })
  },
  startBluetoothDevicesDiscovery() {
    if (this._discoveryStarted) {
      return
    }
    this._discoveryStarted = true
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: true,
      success: (res) => {
        console.log('startBluetoothDevicesDiscovery success', res)
        this.onBluetoothDeviceFound()
      },
      fail(res) {
        console.log('startBluetoothDevicesDiscovery fail', res)
      }
    })
  },
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery()
  },
  onBluetoothDeviceFound() {
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        if (!device.name && !device.localName) {
          return
        }
        const foundDevices = this.data.devices
        const idx = inArray(foundDevices, 'deviceId', device.deviceId)
        const data = {}
        if (idx === -1) {
          data[`devices[${foundDevices.length}]`] = device
        } else {
          data[`devices[${idx}]`] = device
        }
        this.setData(data)
      })
    })
  },
  /**
   * 创建连接
   */
  createBLEConnection(e) {
    // const ds = e.currentTarget.dataset
    // const deviceId = ds.deviceId
    // const name = ds.name
    // const ds = wx.getStorageSync('Dataset')
    const deviceId = wx.getStorageSync('DeviceId')
    const name = wx.getStorageSync('Name')


    console.log('连接设备：', deviceId)
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        console.log('连接成功', res)
        this.setData({
          connected: true,
          name,
          deviceId,
        })
        this.getBLEDeviceServices(deviceId)
      }
    })
    // this.stopBluetoothDevicesDiscovery()
  },
  closeBLEConnection() {
    wx.closeBLEConnection({
      deviceId: this.data.deviceId
    })
    this.setData({
      connected: false,
      chs: [],
      canWrite: false,
    })
  },
  /**
   * 连接成功之后解析该设备中的服务
   */
  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        console.log('分析服务码', res)
        for (let i = 0; i < res.services.length; i++) {
          // 注：解析过程出现两个service，第二个是以前使用的，所以这里添加判断
          if (res.services[i].uuid.indexOf("6E400001") != -1){
            if (res.services[i].isPrimary) {
              this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
              return
            }
          }
        }
      },
      fail(res) {
        console.log('获取服务码错误：', res)
      }
    });
  },
  /**
   * 获取到我们需要的服务之后解析服务中的write和notify服务
   */
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    var that = this;
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        console.log('getBLEDeviceCharacteristics success', res.characteristics)
        for (let i = 0; i < res.characteristics.length; i++) {
          let item = res.characteristics[i]
          if (item.properties.read) {
            wx.readBLECharacteristicValue({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            })
          }
          if (item.properties.write) {
            this.setData({
              canWrite: true
            })
            this._deviceId = deviceId
            this._serviceId = serviceId
            this._characteristicId = item.uuid
            this.writeBLECharacteristicValue("AUTO_ACC");
          }
          if (item.properties.notify || item.properties.indicate) {
            wx.notifyBLECharacteristicValueChange({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
              state: true,
            })
          }
        }
      },
      fail(res) {
        console.error('getBLEDeviceCharacteristics', res)
      }
    });
    // 操作之前先监听，保证第一时间获取数据，即先注册notify服务，随时监听着
    wx.onBLECharacteristicValueChange((characteristic) => {
      const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
      console.log('监听同步返回数据', characteristic);
      console.log('同步单个数据', characteristic.value);
      // console.log('同步数据数组参数', REQdata);
      // 一条数据 添加到这一秒数组中
      var xAF = new Float32Array(characteristic.value.slice(0, 4));
      var yAF = new Float32Array(characteristic.value.slice(4, 8));
      var zAF = new Float32Array(characteristic.value.slice(8, 12));
      var time = new Int32Array(characteristic.value.slice(12, 16));
      var itemData = {
        accelerationX: xAF[0],
        accelerationY: yAF[0],
        accelerationZ: zAF[0],
        time: time[0]
      }

      // 数据量超过300条 清空
      if (null != that.data.datas && that.data.datas.length > 100) {
        that.data.xData = [0];
        that.data.yData = [0];
        that.data.zData = [0];
        that.data.datas = [];
        that.data.secondDatas = [];
      }
      that.data.datas.push(itemData);
      that.data.allDatas.push(itemData);

      // 数据满5条刷新图表 即5*100ms刷新一次
      if (that.data.secondDatas.length > 5){
        for (var i = 0; i < that.data.secondDatas.length;i++){
          that.data.xData.push(that.data.secondDatas[i].accelerationX == null ? 0 : that.data.secondDatas[i].accelerationX);
          that.data.yData.push(that.data.secondDatas[i].accelerationY == null ? 0 : that.data.secondDatas[i].accelerationY);
          that.data.zData.push(that.data.secondDatas[i].accelerationZ == null ? 0 : that.data.secondDatas[i].accelerationZ);
        };
        
        that.data.secondDatas = [];

        that.updateData();
      }

      that.data.secondDatas.push(itemData);
    });
  },
  /**
   * 点击写数据按钮
   */
  // writeAUTO(){
  //   this.writeBLECharacteristicValue("AUTO_ACC");
  // },
  /**
   * 向设备写入命令
   */
  writeBLECharacteristicValue(command) {
    let deviceId=wx.getStorageSync('DeviceId');
    let serviceId=wx.getStorageSync('ServiceId');
    // let characteristicId=wx.getStorageSync('CharacteristicId');
    /*
      对应命令转为16进制的形式
      START   = [83, 84, 65, 82, 84]
      STOP    = [83, 84, 79, 80]
      REQDATA = [82, 69, 81, 68, 65, 84, 65]
    */
    var buffer = stringToBytes(command)
    wx.writeBLECharacteristicValue({
      // deviceId: deviceId?deviceId:this._deviceId,
      // serviceId:serviceId?serviceId: this._serviceId,
      // characteristicId:characteristicId?characteristicId: this._characteristicId,
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: buffer,
      success: function(res){
        console.log("发送成功", res)
      },
      fail(res){
        console.log("发送失败", res)
      }
    })
  },
  closeBluetoothAdapter() {
    wx.closeBluetoothAdapter()
    this._discoveryStarted = false
  },

  /////////////////////////  写文件  /////////////////////////////

  /**
   * 写文件
   */
  writeFile(){
    console.info("总数据：", JSON.stringify(this.data.allDatas));
  }
})
